/*******************************************************************************
 * Copyright (c) 2006 CEA List.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     CEA List - initial API and implementation
 *******************************************************************************/
package com.cea.papyrus.diagram.classdiagram.editpart;

import java.util.Iterator;

import org.eclipse.draw2d.XYLayout;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.commands.CompoundCommand;
import org.eclipse.gef.requests.ChangeBoundsRequest;

import com.cea.papyrus.core.commands.Di2AddCommand;
import com.cea.papyrus.core.commands.GraphNodeSetConstraintCommand;
import com.cea.papyrus.core.editpart.GraphNodeEditPart;
import com.cea.papyrus.core.editpart.LayoutEditPolicy;
import com.cea.papyrus.diagraminterchange2.di2.GraphElement;
import com.cea.papyrus.diagraminterchange2.di2.GraphNode;

/**
 * LayoutEditPolicy for the Class Diagram.
 */
public class ClassLayoutEditPolicy extends LayoutEditPolicy {

	/**
	 * Creates a new {@link ClassLayoutEditPolicy} with the given layout.
	 * 
	 * @param layout the layout of the diagram
	 */
	public ClassLayoutEditPolicy(XYLayout layout) {
		super(layout);
	}
	
//	protected Command getAddCommand(Request generic) {
//		ChangeBoundsRequest request = (ChangeBoundsRequest)generic;
//		List editParts = request.getEditParts();
//		List newList = new ArrayList() ;
//		for (int i = 0; i < editParts.size(); i++) {
//			if (!(editParts.get(i) instanceof TemplateSignatureEditPart) && !(editParts.get(i) instanceof RedefinableTemplateSignatureEditPart)) {
//				newList.add(editParts.get(i)) ;
//			}
//		}
//		((ChangeBoundsRequest)generic).setEditParts(newList) ;
//		return super.getAddCommand(generic) ;
//	}
	
	/**
	 * used to create an add command.
	 * 
	 * @param childEditPart the editpart that is conecerned
	 * @param constraint to set on this editpart
	 * @param request to create an add command
	 * 
	 * @return the addcommand
	 */

	protected Command createAddCommand(ChangeBoundsRequest request, EditPart childEditPart, 
			Object constraint) {

		CompoundCommand c= new CompoundCommand();
		if (childEditPart instanceof TemplateSignatureEditPart) {
			GraphElement parentGE = (GraphElement) this.getHost().getModel();
			
			Iterator itgraphChild = ((TemplateSignatureEditPart) childEditPart).getGraphNode().getSemanticChild().iterator();
			while (itgraphChild.hasNext()) {
				GraphNode gn = (GraphNode) itgraphChild.next();
				Rectangle r = new Rectangle(gn.getPosition().x, gn
						.getPosition().y, gn.getSize().width,
						gn.getSize().height);
				GraphNodeSetConstraintCommand locationCommand = new GraphNodeSetConstraintCommand(
						gn, request, request.getTransformedRectangle(r));
				c.add(locationCommand);
			}
			
			if (((TemplateSignatureEditPart) childEditPart).getGraphNode().getSemanticParent() != parentGE) {
				return null;
			}
		}
		if (childEditPart instanceof RedefinableTemplateSignatureEditPart) {
			GraphElement parentGE = (GraphElement) this.getHost().getModel();
			
			Iterator itgraphChild = ((RedefinableTemplateSignatureEditPart) childEditPart).getGraphNode().getSemanticChild().iterator();
			while (itgraphChild.hasNext()) {
				GraphNode gn = (GraphNode) itgraphChild.next();
				Rectangle r = new Rectangle(gn.getPosition().x, gn
						.getPosition().y, gn.getSize().width,
						gn.getSize().height);
				GraphNodeSetConstraintCommand locationCommand = new GraphNodeSetConstraintCommand(
						gn, request, request.getTransformedRectangle(r));
				c.add(locationCommand);
			}
			
			if (((RedefinableTemplateSignatureEditPart) childEditPart).getGraphNode().getSemanticParent() != parentGE) {
				return null;
			}
		}
		c.add(super.createAddCommand(request, childEditPart, constraint));
		if(childEditPart instanceof PackageEditPart||childEditPart instanceof ClassEditPart){
			GraphElement parentGE=(GraphElement)this.getHost().getModel();
			Iterator itgraphChild= ((GraphNodeEditPart)childEditPart).getGraphNode().getSemanticChild().iterator();
			while( itgraphChild.hasNext()){
				GraphNode gn= (GraphNode)itgraphChild.next();
				Point delta= gn.getPosition().getCopy().getTranslated(((GraphNodeEditPart)childEditPart).getGraphNode().getPosition().getCopy().negate());
				
				Rectangle r= new Rectangle(gn.getPosition().x,gn.getPosition().y, gn.getSize().width,gn.getSize().height);
				r.setLocation(((Rectangle)constraint).getLocation().getCopy());
				r.setLocation(r.getLocation().translate(delta));
				GraphNodeSetConstraintCommand locationCommand = new GraphNodeSetConstraintCommand(gn,
						request,
						r);
				c.add(locationCommand);
				Di2AddCommand di2add =new Di2AddCommand(gn, ((GraphNodeEditPart)childEditPart).getGraphNode(), getCurrentTypeDiagram());
				c.add(di2add);
			}
		}
		return c;
	}
	
	
}
